﻿/***
	
	# CopyRights By Pr (yslee96@naver.com / webmaster@prev.kr) 
		
	@ Author Pr (yslee96@naver.com)
	
	@ http://prev.kr
	
***/


package  kr.prev.swe {
	
	import flash.utils.ByteArray;
	
	public class SWE {
		
		public static const CONTENT_NAME:String = "T-NAME"
		public static const CONTENT_ICON:String = "B-ICON"
		public static const CONTENT_SWF_DATA:String = "B-SWFD"
		public static const CONTENT_COPYRIGHT:String = "T-COPR"
		public static const CONTENT_PUBLISHER:String = "T-PUBL"
		/**
		
			프레임의 ID값들
			
			텍스트 프레임은 'T-' 가 붙고 바이너리 프레임은 'B-' 가 붙는다 (현재 버전 기준)
		
		**/
		
		
		private var _bytes:ByteArray
		/**
		
			SWE file 바이트어레이/바이너리
			
		**/
		
		private var _SWEVersion:String
		/**
		
			SWE file 버전
			
		**/
		
		private var _frames:Vector.<SWEFrame> = new Vector.<SWEFrame>()
		/**
		
			SWE frames
			
		**/
		
		public const classVersion:String = '1.1'
		/**
		
			현재 이 클래스의 버전
			
			fuse()할때의 버전
			
		**/
		
		public function get bytes():ByteArray {
			return _bytes
		}
		
		public function get SWEVersion():String {
			return _SWEVersion
		}
		
		public function get frames():Vector.<SWEFrame> {
			return _frames
		}
		
		public function SWE (bytes:ByteArray=null) {
			if (bytes) {
				_bytes = new ByteArray()
				bytes.position = 0
				bytes.readBytes(_bytes, 0, bytes.length)
				
				analyze(bytes)
			}
		}
		/**
		
			SWE 생성
			
			첫번째 인수가 null이 아닐때 첫번째 인수로 analyze() 실행
			
		**/
		
		public function analyze(bytes:ByteArray):void {
			
			_bytes = new ByteArray()
			bytes.position = 0
			bytes.readBytes(_bytes, 0, bytes.length)
			
			var $bytes:ByteArray = new ByteArray()
			bytes.position = 0
			bytes.readBytes($bytes, 0, bytes.length)
			
			
			if ($bytes.readUTFBytes(3) != 'SWE') {
				return
			}
			
			_SWEVersion = $bytes.readShort() +'.' + $bytes.readShort()
			
			while ($bytes.bytesAvailable > 0 ) {
				var frameID:String = $bytes.readUTFBytes(6)
				var frameType:String = frameID.substr(0,1) // Text(T) Binary(B)
				
				var temp_length:uint = $bytes.readUnsignedInt()
				var temp:ByteArray = new ByteArray()
				
				if (temp_length) {
					$bytes.readBytes(temp, 0, temp_length )
				}
				
				if (frameType == "T") { //Text Frame
					addTextFrame(frameID, temp.readUTFBytes(temp_length), temp )
				}else {
					addFrame(frameID, temp)
				}
				
			}
			
		}
		/**
		
			SWE 프레임을 첫번째 인수 bytes로 분석하고 frames 벡터에 담는다
			
		**/
		
		
		public function addFrame(ID:String, bytes:ByteArray):SWEFrame {
			var frame:SWEFrame = new SWEFrame(ID, bytes)
			_frames.push(frame)
			return frame
		}
		/**
		
			frames 벡터에 프레임을 추가한다
			
		**/
		
		public function addTextFrame(ID:String, content:String, bytes:ByteArray=null):SWEFrame {
			var temp:ByteArray = new ByteArray()
			if (bytes == null) {
				temp.writeUTFBytes(content)
			}else {
				temp.writeBytes(bytes, 0, temp.length)
			}
			var frame:SWEFrame = new SWEFrame(ID, temp, content)
			_frames.push(frame)
			return frame
		}
		/**
		
			frames 벡터에 텍스트 프레임을 추가한다
			
		**/
		
		public function getFrame(ID:String):SWEFrame {
			for (var i:uint=0; i<_frames.length; i++) {
				if (_frames[i].ID == ID) {
					return _frames[i]
				}
			}
			return null
		}
		/**
		
			frames 벡터에서 해당 ID값을 지닌 프레임을 추출한다
			
		**/
		
		public function fuse():ByteArray {
			
			var fusedBytes:ByteArray = new ByteArray()
			fusedBytes.writeUTFBytes('SWE')
			
			var version:Array = classVersion.split(".")
			fusedBytes.writeShort( version[0] )
			fusedBytes.writeShort( version[1] )
			
			for (var i:uint=0; i<_frames.length; i++){
				 _frames[i].bytes.position = 0
				fusedBytes.writeUTFBytes( _frames[i].ID )
				fusedBytes.writeUnsignedInt( _frames[i].bytes.length )
				fusedBytes.writeBytes( _frames[i].bytes, 0, _frames[i].bytes.length )
			}
			
			return fusedBytes
			
		}
		/**
		
			frames 벡터로 SWE의 ByteArray를 만들어낸다
			
			analyze()의 역함수
			
		**/
		
		public function toString():String {
			return "[ SWE ver " + _SWEVersion + " frames:" + _frames.length + " ]"
		}
		

	}
	
}
